home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
201-225
/
disk_216
/
virusx
/
virusx.c
< prev
next >
Wrap
Text File
|
1992-05-06
|
68KB
|
1,985 lines
/************************************************************************/
/* */
/* */
/* VirusX */
/* */
/* by Steve Tibbett */
/* */
/* */
/* Please - if you find a new virus, Send me a copy! */
/* (And warn me it's on the disk!). I want to keep */
/* this program current. (Feel free to put something */
/* neat on the disk also!) */
/* */
/* This version of VirusX is done with the Lattice 5.0 */
/* compiler. The Lattice compiler, with the help of John Toebes, */
/* gave me an executable almost 4K smaller than the best I could */
/* get out of Manx. Reason enough for me to switch! */
/* */
/* The Makefile included in the "source.zoo" file you should have */
/* gotten in the VirusX.Zoo file this came from, is set up for the */
/* MANX Make Utility. Switching to Lattice's LMK should be easy, */
/* but I've had no reason to. The important thing is the command */
/* line switches and the BLINK command line. */
/* */
/* Thanks to John Toebes for a lot of help getting it going, and */
/* thanks to Dan James for providing the routine down at the bottom */
/* that actually takes the IRQ Virus out of executable files. */
/* */
/************************************************************************/
/* */
/* History: */
/* -------- */
/* April '88 or so: V1.0 written and released. */
/* A few days later: V1.01 released. V1.0 wrote garbage to the */
/* disk if it was write protected then fixed. */
/* 27-March-88: V1.2 released. V1.2's purpose in life was */
/* to deal with the Byte Bandit virus. */
/* (Actually, it's well after midnight - make */
/* that March 28th. :) */
/* 28-March-88: Oops, V1.2 was 3K or so bigger than it needed */
/* to be. Fix it, release v1.21. */
/* 15-June-88: V1.3, V1.2 cleaned up and made smaller. */
/* 8-July-88: V1.4. Revenge virus checking, Viewbooting, */
/* check for SCA in RAM, more cleaning up. */
/* 24-July-88: V1.5, only change was the addition of the */
/* Byte Warrior virus. */
/* 1-Aug-88: V1.6 (busy week), Dan Mosedale sent me the */
/* Northstar Virus. Nuked it. */
/* 18-Aug-88: V1.7 - after 2 weeks off, got the Obelisk */
/* Softworks crew virus. */
/* a few days later: V1.71, can't remember why. */
/* September Sometime: Biggest mistake of my life, released V2.0. */
/* 3 days later: Bigger mistake: Released V2.01 - which was */
/* 2.0 with another bug added. Argh. */
/* 6-Nov-88: Finally got some time to clean things up, */
/* check out the startup code bugs, clean up the */
/* docs and source, and release V2.1. There */
/* haven't been any new viruses in about a month */
/* now, but I hear one or two are on the way. */
/* 31-Dec-88: Got the IRQ virus yesterday. Neat one! */
/* Releasing V3.0 tonite or tomorrow to handle */
/* it. See description below. */
/* 04-Jan-89: Got 2 new viruses, released 3.1. */
/* 18-Feb-89: And boy, am I tired. 8 (count 'em) 8 new */
/* viruses in this version. Ack! DOUBLE */
/* the last version. New option: CHECK, good */
/* for including VirusX with a commercial */
/* program. V3.20 */
/* */
/************************************************************************/
/* */
/* Viruses Dealt With: */
/* ------------------- */
/* */
/* SCA - The SCA is the simplest virus to deal with, */
/* as it's not actually DOING anything except */
/* hiding in memory, until you reboot. */
/* We just look at CoolCapture and fix it to get */
/* it out of RAM. */
/* */
/* Byte Bandit - The Byte Bandit virus takes the DoIO() vector */
/* and redirects it through itself. Thus, any */
/* attempt to read or write the boot block (ie, */
/* AmigaDOS trying to figure out what kind of */
/* disk it is) results in the BB writing itself */
/* onto that disk. VirusX couldn't just rewrite */
/* the boot block, we have to get him out of RAM */
/* first. This virus also has an interrupt that */
/* crashes the machine every 5 minutes or so */
/* after it's infected a few of your disks. Ow. */
/* It stays in memory not via the Capture */
/* vectors, but by a Resident module. */
/* */
/* Revenge - Basically, a Byte Bandit clone except it will */
/* bring up an obscene pointer a few minutes */
/* after you reboot. We treat it much like the */
/* byte bandit. */
/* */
/* Byte Warrior - Jumps right into 1.2 Kickstart. Won't work */
/* under 1.3. Hangs around via Resident struct, */
/* doesn't do any damage. */
/* */
/* North Star - Like SCA, hangs around via CoolCapture, */
/* killing CoolCapture kills the North Star. */
/* */
/* Obelisk Softworks Crew */
/* - Hangs around via CoolCapture, also */
/* watches reads of DoIO() (but doesn't */
/* infect EVERY disk - onlyt ones you boot */
/* off of) */
/* */
/* IRQ - This is the FIRST Non-Bootblock Virus. */
/* It copies itself from place to place via the */
/* first executable program found in your */
/* startup-sequence. It SetFunction's */
/* OldOpenLibrary(), has a KickTagPtr, */
/* and lives in the first hunk of an */
/* infected program. */
/* THANKS! to Gary Duncan and Henrik Clausen for */
/* being the first to send this one to me! */
/* */
/* Pentagon Circle - This one looks at the DoIO vector, and has */
/* a CoolCapture vector. It will write itself */
/* over any virus inserted, but not onto */
/* anything else. (Neat idea!). No danger, */
/* easy to eliminate. Holding left button */
/* while booting with this one shows different */
/* screen colour, but doesn't get rid of it. */
/* Thanks to Bill at CMI (CMI*BILL on Plink) */
/* for sending me this one! */
/* */
/* SystemZ Virus Protector */
/* - I took this one out. It's not really a */
/* 'Virus' in that it won't overwrite a disk */
/* without asking you first. Besides, it seems */
/* a lot of people LIKE the SystemZ Virus */
/* Protector (though it isn't perfect). */
/* */
/* Lamer Exterminator - THIS one was a bugger. Yet another virus */
/* aimed at hurting people. Y'see, a Lamer */
/* is apparently the worst kind of pirate - */
/* one who doesn't crack software, doesn't */
/* write software, just collects names and */
/* addresses and collects and spreads software. */
/* Lamers don't do anybody any good - and the */
/* guy behind this Virus took it upon himself */
/* to make their (and our) lives miserabler. */
/* Anyway, this virus loads into RAM into a */
/* different location every time (using a */
/* random location). It is encrypted on the */
/* disk so you can't SEE the name of it, and */
/* it never actually SHOWS the name (but it's */
/* definately there). It changes the */
/* encryption key used each time it is written */
/* back to disk. It has a counter and will */
/* wait until the machine has been reset 2 times */
/* OR until 3 disks have been infected, and will */
/* then pick a DATA block (Only a DATA block - */
/* FFS disks are safe, I guess), randomly, and */
/* will write the word 'LAMER!' all through it. */
/* This is obviously not good, and will cause */
/* random disk errors. This is the worst kind */
/* of havoc to wreak on the new user - and this */
/* virus is EVERYWHERE! I've gotten it from 5 */
/* people in the last week alone (all from */
/* different countries! Ack!). Anyways, credit */
/* for being the first with this one is */
/* Christian Schneider. Thanks, Christian! */
/* Might as well break the margin convention here, eh? Anyways, */
/* something else I thought of about this virus: It introduces a NEW */
/* way for a Virus to stay in RAM. Y'see, if ExecBase is okay at */
/* reboot time (Exec keeps a checksum, among other things, and checks */
/* to see if anything has been corrupted quite carefully). Anyways, */
/* if Exec thinks ExecBase is okay, it doesn't bother rebuilding it. */
/* Sooo, this virus sets the SumKickData() vector to point at itself. */
/* Then at Reboot when this vector gets called after reset, the virus */
/* ReInstalls himself. At least this is what I think is happening. */
/* This virus sets up a Resident structure, but never sets the Match */
/* Word - either this means we don't need the MatchWord or it means */
/* his SumKickData() is doing the recovery job - either way, it's */
/* new! 3 points for originality. */
/* */
/* Graffiti - The first virus to come with rotating 3-d graphics! */
/* It's neat - you might want to trigger it (I'm not sure */
/* how) before nuking it. Anyway, this one just sets */
/* CoolCapture(), does something with DoIO() during the */
/* reboot but sets it back to normal before anybody gets */
/* to look at it. Lots of code is taken by the graphics */
/* stuff. I just clear the CoolCapture vector. [yawn] */
/* */
/* Old Northstar - Poof. */
/* */
/* 16 Bit Crew - Well, I didn't actually have to DO anything to get */
/* VirusX to recognize it... because it seems to operate */
/* like the Graffiti Virus. If the 16 bit crew is in */
/* RAM, VirusX will say it removed the Graffiti virus. */
/* Oh well. 8-) */
/* */
/* DiskDoktor - I spent more time on this one than on any other. */
/* Y'see, this virus does lots of things. The first one */
/* for some reason was quite funny to me. heh */
/* What it would do is after you have rebooted 5 times, */
/* each time you reboot after that, the virus would eat */
/* 10K times the total number of reboots - so after */
/* rebooting 10 times, you would be short about 100K. */
/* This virus also starts up another TASK. I'm not */
/* exactly sure when it happens, but another task named */
/* 'clipboard.device' will appear at a priority of -120, */
/* and will continually bash the Virus' vectors into the */
/* Coldcapture, Coolcapture, Warmcapture (which it sets */
/* to $ff000000 just to annoy), and the DoIO() vector. */
/* When I was working on this one, I figured I just had */
/* to restore the old values to the DoIO() vector, but as */
/* soon as I did so, the Virus restored them - and since */
/* I didn't disassemble the entire thing, I didn't realize*/
/* this until I wasted time looking for other faults. */
/* This one also allocates some memory, copies some code */
/* out of Exec into this memory, and executes it. I */
/* never bothered to figure out why - Once it's gone, it's*/
/* gone. */
/* */
/* Thanks also to Robb Walton for being the first to send one of the */
/* other ones, (but I can't remember which one anymore... 8-( ) */
/************************************************************************/
/* */
/* Notes on making VirusX yourself: The source is included mainly */
/* for your perusal, not so that you can modify it and redistribute */
/* it. I've modified Manx's _main.c module to make the detach */
/* from the initial CLI work properly. I can't redistribute this */
/* module since it's copyright manx, so here's VirusX without it. */
/* It will compile and run, but if you run it from WB, it won't quit. */
/* The version I've supplied should do everything just fine. */
/* */
/************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <devices/bootblock.h>
#include <devices/trackdisk.h> /* / */
#include <exec/execbase.h> /* <-- include files */
#include <exec/memory.h> /* \ */
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <pragmas/all.h>
#include <proto/all.h>
#include <String.h>
#include "virusx.i" /* Virusx.i is an ANSI thing. It's got Protoypes. */
/* (or used to anyway) */
/* Latticeisms */
/* What's that you say? C is hard to read? */
void MemCleanup() {}
void RawDoFmt(char *, long *, void (*)(), char*);
#pragma syscall RawDoFmt 20a ba9804
void __regargs prbuf(char c);
int __regargs sprintf(char *buf, char *ctl, char *args) { RawDoFmt(ctl, (long *)&args, prbuf, buf); return(strlen(buf)); }
void __regargs prbuf(char c) {__builtin_emit(0x16c0);}
/******************************************************************/
/* In case you're interested, that little mess above is a routine */
/* supplied by John Toebes which changes sprintf() from using the */
/* compiler's library into something that uses the ROM code found */
/* in Kickstart. Sooo, it made VirusX about 1.2K or so smaller!! */
/* Feel free to steal this and use it wherever. However, the new */
/* sprintf function can't handle a lot of things - check the Exec */
/* manual (I believe) for details. Neat formatting here, eh? 8-) */
/******************************************************************/
char WhatHappened; /* huh?? */
/******************************************************************/
/* These string constants are used in multiple places, and thus */
/* save bytes by having only one copy of them. */
/******************************************************************/
char TITLETEXT[] = "VirusX 3.20 by Steve Tibbett";
char TDName[] = "trackdisk.device";
char copystring[] = "(Copy Count on this disk: %ld)";
char ITBodyText[80];
char CaptureStr[] = "Capture is pointing at $";
char text[] = "DF6: Boot Sectors";
char VN_OBELISK[] = "Obelisk";
char VN_NORTHSTAR[] = "North Star";
char VN_SCA[] = "SCA";
char VN_BYTEBANDIT[] = "Byte Bandit";
char VN_BYTEWARRIOR[] = "Byte Warrior";
char VN_REVENGE[] = "Revenge";
char VN_IRQ[] = "IRQ";
char VN_PENTAGON[] = "Pentagon Circle";
char VN_LAMER[] = "Lamer Exterminator";
char VN_HCS[] = "H.C.S.";
char VN_UFOX[] = "UltraFox";
char VN_DDOC[] = "DiskDoc";
char VN_GRAFFITI[] = "Graffiti";
char VN_Bit16[] = "16 Bit Crew";
char VN_PHANTASM[] = "Phantasmumble"; /* Can't remember the whole name */
char VN_OLDNSTAR[] = "Old Northstar";
/********************************************************************/
/* These counters are for the Info window, one for each virus. */
/********************************************************************/
int ObeliskCount;
int NorthStarCount;
int SCACount;
int ByteBanditCount;
int ByteWarriorCount;
int RevengeCount;
int IRQFound;
int PentagonCount;
int LamerXCount;
int HCSCount;
int UFoxCount;
int DDocCount;
int GRAFFITICount;
int Bit16Count;
int PhantasmCount;
int OldNStarCount;
/*******************************************************************/
/* Miscellaneous variables. */
/*******************************************************************/
long ChangeCount[4]; /* TD_CHANGECOUNT for 4 drives */
long LastSum; /* Used in the checksumming */
long error; /* sort of a temporary variable */
char WindowBig; /* TRUE if the window is big */
struct Port *diskport; /* trackdisk's port. */
struct IOStdReq *diskreq; /* trackdisk's IOStdReq */
long DisksChecked, DisksInstalled; /* for title bar info */
long VirusBase; /* ick, whatta name! */
struct IntuitionBase *IntuitionBase; /* For Library Bindings */
struct GfxBase *GfxBase;
struct Window *Window;
struct IntuiMessage *Message;
struct ExecBase *ExecBase;
struct IOStdReq *TimerReq;
struct MsgPort *TimerPort;
static long fp;
char Keepgoing; /* A flag. It's false when we want out. */
long x, y, i; /* Left over from my using Basic */
char flag; /* Another flag. Lets start our own country. */
LONG thing1, thing2;
struct NewWindow NewWindow =
{
128,0, 309,10, 0,1,
DISKINSERTED | CLOSEWINDOW |VANILLAKEY | NEWSIZE | MOUSEBUTTONS, /* IDCMP Flagz */
WINDOWDRAG | WINDOWDEPTH | RMBTRAP | WINDOWCLOSE | NOCAREREFRESH, /* Windo Flagz */
NULL, NULL,TITLETEXT,
NULL,NULL,0,0,0,0,WBENCHSCREEN,
};
struct RastPort *RP;
#define BSIZE 40 /* Ha! I'm not telling what this is! */
/*******************************************************************/
/* diskbuffer is where all disk io goes to. it's 3*512 rather */
/* than 2*512, because I believe one of the viruses watches for */
/* reads of 1024 bytes, so I'm just being safe. */
/*******************************************************************/
UBYTE *diskbuffer;
/************************************************************************/
/* Warning messages. These messages get modified before being */
/* displayed (Unless you DO have a DF9:) */
/************************************************************************/
char TEXTPTR[] = "Danger: The disk in DF9: is";
char NBCTEXT[] = "Danger: The disk in DF9: has"; /* What a waste, eh? */
char CopyText[40];
/*************************************************************************/
/* This is a byte by byte copy of working boot block code. Check it */
/* out if you like. This is what gets written back to the disk when */
/* you ask VirusX to fix a disk. */
/*************************************************************************/
unsigned char bootblock[] = { 'D', 'O', 'S', 0,
0xc0, 0x20, 0x0f, 0x19, 0x00, 0x00, 0x03, 0x70, 0x43, 0xfa, 0x00, 0x18,
0x4e, 0xae, 0xff, 0xa0, 0x4a, 0x80, 0x67, 0x0a, 0x20, 0x40, 0x20, 0x68,
0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 0x70, 0xff, 0x60, 0xfa, 0x64, 0x6f,
0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x00, 0x00,
0x00, 0x00};
/********************************************************************/
/* My intuition defines. There's lots of 'em - theyre self explan.*/
/********************************************************************/
struct TextAttr TxtAt_Plain =
{
"topaz.font", 8, FS_NORMAL, FPF_ROMFONT
};
/*** Non SCA warning requester IntuiText's ***/
struct IntuiText Body2 =
{
0, 1, JAM2, 20,18, &TxtAt_Plain, "Nonstandard Boot Code!", NULL
};
struct IntuiText Body1 =
{
0,1, JAM2, 20, 8, &TxtAt_Plain, (UBYTE *)NBCTEXT, &Body2
};
/*- This one says "The disk in DFx: is" -*/
struct IntuiText GenericFirstBody =
{
0,1, JAM2, 20,8,&TxtAt_Plain, (UBYTE *)TEXTPTR, 0
};
/***** Generic IntuiTexts used as of V1.7 ******/
struct IntuiText GenericDiskBody =
{
0,1, JAM2, 20,18, &TxtAt_Plain,ITBodyText, &GenericFirstBody
};
struct IntuiText SCAPos =
{
0,1, JAM2, 7,3, &TxtAt_Plain, "Remove it", NULL
};
struct IntuiText Repair =
{
0,1, JAM2, 7,3, &TxtAt_Plain, "Repair it", NULL
};
struct IntuiText SCANeg =
{
0,1, JAM2, 7,3, &TxtAt_Plain, "Ignore it", NULL
};
/* Special cases (display copy count) */
/***** BBANDIT Requester IntuiText's ******/
struct IntuiText BBDiskbody2 =
{
0,1, JAM2, 20,30, &TxtAt_Plain, CopyText, &GenericFirstBody
};
struct IntuiText BBDiskbody =
{
0,1, JAM2, 20,18, &TxtAt_Plain, ITBodyText, &BBDiskbody2
};
/***** Revenge on Disk Requester IntuiText's ******/
struct IntuiText RevDiskbody3 =
{
0,1, JAM2, 20,30, &TxtAt_Plain, CopyText, &GenericFirstBody
};
struct IntuiText RevDiskbody =
{
0,1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "infected with the -Revenge- VIRUS!", &RevDiskbody3
};
/***** Generic Notice - Removed from Memory ****/
struct IntuiText GRB3 =
{
0,1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "in memory, and is now disabled. See the", NULL
};
struct IntuiText GRB2 =
{
0,1, JAM2, 20,28, &TxtAt_Plain,(UBYTE *) "documentation for more information!", &GRB3
};
struct IntuiText GenericRAMBody =
{
0,1, JAM2, 20, 8, &TxtAt_Plain, ITBodyText, &GRB2
};
struct IntuiText BBMPos =
{
0,1, JAM2, 7, 3, &TxtAt_Plain, " Thanks! ", NULL
};
struct IntuiText Mem3 =
{
0,1, JAM2, 20,28, &TxtAt_Plain,(UBYTE *) "some other utility is the cause of it.", NULL
};
struct IntuiText Mem2 =
{
0,1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "This could mean a new Virus is in RAM, or", &Mem3
};
struct IntuiText Mem1 =
{
0,1, JAM2, 20, 8, &TxtAt_Plain, 0 , &Mem2
};
/***** Write Protect Error Requester IntuiText's ******/
struct IntuiText ERRBody2 =
{
0,1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "Write Protected.", NULL
};
struct IntuiText ERRBody =
{
0,1, JAM2, 20,8, &TxtAt_Plain, (UBYTE *)"DISK ERROR: Disk is", &ERRBody2
};
struct IntuiText ERRPos =
{
0,1, JAM2, 7,3, &TxtAt_Plain, "Retry", NULL
};
struct IntuiText ERRNeg =
{
0,1, JAM2, 7,3, &TxtAt_Plain, "Cancel", NULL
};
/***** Rewrite block? Really? ******/
struct IntuiText REWBody3 =
{
0,1, JAM2, 20,28, &TxtAt_Plain,(UBYTE *) "boot sectors?", NULL
};
struct IntuiText REWBody2 =
{
0,1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "rewrite that disk's boot", &REWBody3
};
struct IntuiText REWBody =
{
0,1, JAM2, 20,8, &TxtAt_Plain, (UBYTE *)"Are you sure you want to", &REWBody2
};
struct IntuiText REWPos =
{
0,1, JAM2, 7,3, &TxtAt_Plain, "Yes", NULL
};
struct IntuiText REWNeg =
{
0,1, JAM2, 7,3, &TxtAt_Plain, "No!", NULL
};
/*********************Da Beginnin*************************/
void main(argc, argv)
int argc;
char **argv;
{
if (argc == 3)
{
NewWindow.LeftEdge = atoi(argv[1]);
NewWindow.TopEdge = atoi(argv[2]);
};
WindowBig = FALSE;
/* Come on, folks, is intuition ever NOT going to be available???? */
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L);
/* Same with GfxBase. If GfxBase is gone, we DESERVE to crash. */
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L);
ExecBase = (struct ExecBase *)OpenLibrary("exec.library", 0);
diskbuffer = AllocMem((long)3*512, (long)MEMF_CHIP|MEMF_CLEAR);
if (diskbuffer == 0)
{
/* Okay, okay, it's messy and doesn't close the libraries it
opens. Look, if we can't get a measley 1.5K, then the
system is probably going to crash before the user finds out
what hit him, and he probably won't blame me. */
exit(10);
};
/* We use the same port/request through the whole program. Works OK. */
diskport = CreatePort(0L,0L);
diskreq = CreateStdIO(diskport);
Window = OpenWindow(&NewWindow);
if (Window == NULL)
goto Quitter; /* No memory to open little window! */
RP = Window->RPort;
/* This does some setup stuff, I guess, eh? */
SetUp();
/* Check for Byte Bandit, SCA, Revenge and ByteWarrior, etc. in RAM. */
CheckMemoryForViruses();
/* Hmmm, wonder what this does. */
CheckMemoryForIRQVirus();
CheckBlock();
if (argc != 2) /* New Feature: Virusx CHECK will only check disks then quit */
DoLittle(); /* The main loop. Do Little. Ya. */
Quitter:
if (Window != 0) CloseWindow(Window);
if (diskport != 0) DeletePort(diskport);
if (diskreq != 0) DeleteStdIO(diskreq);
CloseLibrary(GfxBase); /*
CloseDoor(DoorBase);
CloseLibrary(IntuitionBase); hahah bet I fooled you */
CloseLibrary((struct Library *)ExecBase);
FreeMem(diskbuffer, (long)3*512);
exit(0);
/* DoorBase?? */
}
/*********************/
DoLittle()
{
long Code; /* for storing our IntuiMessage stuff */
long Class;
char KG2; /* KeepGoing 2. Another booleean. */
KG2 = TRUE;
SetAPen(RP, 1L);
SetBPen(RP, 0L);
SetDrMd(RP, (long)JAM2);
while (KG2 == TRUE)
{
Message = (struct IntuiMessage *)GetMsg(Window->UserPort);
if (Message == 0)
{
CheckMemoryForIRQVirus();
Delay(50);
continue;
};
Class = Message->Class;
Code = Message->Code;
ReplyMsg((struct Message *)Message);
if (Class == CLOSEWINDOW)
{
KG2 = FALSE;
continue;
};
if (Class == MOUSEBUTTONS)
if (Code == MENUDOWN)
{
Class = VANILLAKEY;
Code = 'i';
}
else continue;
if (Class == VANILLAKEY)
{
char flag;
switch (toupper(Code))
{
case 'I':
if (WindowBig == TRUE) WindowBig = FALSE;
else WindowBig = TRUE;
if (WindowBig == TRUE)
{
if (Window->TopEdge > 0) MoveWindow(Window, 0L, (long)-Window->TopEdge);
SizeWindow(Window, 0L, 200-(Window->Height));
} else SizeWindow(Window, 0L, -Window->Height + 10);
WaitForNewSize();
break;
case 'C':
for (x=0; x<4; x++) ChangeCount[x] = 10000;
CheckBlock();
default:
flag = ShowAscii(Code);
if (flag == 1) CheckBlock();
};
if (WindowBig == TRUE) DoStats();
};
if (Class == DISKINSERTED)
{
CheckBlock();
if (WindowBig == TRUE) DoStats();
};
};
}
/************************************************/
/* Opens trackdisk, finds out who's out there, */
/* and sets Changecount up accordioningly. */
/************************************************/
SetUp()
{
long x;
for (x = 0; x < 4; x++) /* go thru all 4 possible drives */
{
ChangeCount[x] = 1000;
error = OpenDevice(TDName,(long)x,diskreq,0L);
if (error > 0)
{
ChangeCount[x] = -1;
} else CloseDevice(diskreq);
};
}
/*********************************************************/
/* This routine returns which drive changed disks lately */
/*********************************************************/
WhoChanged()
{
char RetVal = -1; /* The value we'll return */
for (x = 0; x < 4; x++)
{
if (ChangeCount[x] == -1)
continue; /* no drive here */
error = OpenDevice(TDName,(long)x,diskreq,(long)0);
if (error > 0)
continue; /* no drive here */
diskreq->io_Command = TD_CHANGESTATE;
DoIO(diskreq);
if (diskreq->io_Actual != 0)
{
CloseDevice(diskreq);
continue;
};
diskreq->io_Command = TD_CHANGENUM;
DoIO(diskreq);
if (diskreq->io_Actual != ChangeCount[x])
{
RetVal = x;
ChangeCount[x] = diskreq->io_Actual;
CloseDevice(diskreq);
break;
};
CloseDevice(diskreq);
};
return(RetVal);
}
/****************************************************************/
/* Figures out which drive changed disks (using WhoChanged(), */
/* And checks it. Calling this after every DISKINSERTED is OK.*/
/****************************************************************/
CheckBlock()
{
/* How many register vars can I use, anyway? */
register long Sum, Virus;
register long a, Unit;
char SCA, ByteWarrior, Revenge, BBandit;
char NorthStar, Obelisk, Pentagon, LamerX, HCS;
char DDoc, GRAFFITI, Bit16, Phantasm, OldNStar;
char UFox;
unsigned long *iptr;
unsigned long *ptr;
char drivename[10];
while ((Unit = WhoChanged()) != -1)
{
strcpy(drivename, "DF0:");
drivename[2] = '0'+Unit;
SCA = FALSE;
BBandit = FALSE;
Revenge = FALSE;
ByteWarrior = FALSE;
NorthStar = FALSE;
Obelisk = FALSE;
Pentagon = FALSE;
LamerX = FALSE;
UFox = FALSE;
HCS = FALSE;
DDoc = GRAFFITI = Bit16 = Phantasm = OldNStar = FALSE;
/* Unit # to open is returned by "WhoChanged()" up above. */
if (Unit == -1) return;
error = OpenDevice(TDName,(long)Unit,diskreq,0L);
if (error > 0) return;
DisksChecked++;
error = ReadBlock();
CloseDevice(diskreq);
if (error == FALSE) return;
ptr = (long *)diskbuffer;
iptr = (long *)diskbuffer;
if (iptr[0] != ID_DOS_DISK) return; /* No DOS/0 */
Sum = 0;
for (a=0; a<256; a++)
{
LastSum = Sum;
Sum = Sum + ptr[a];
if (LastSum > Sum) Sum++; /* took me a while to figger this out */
}
if (Sum != 0)
{
CheckDriveForIRQ(drivename);
return; /* if it's not bootable, we DONT want it! */
};
if (diskbuffer[0x40] == 0xff)
if (diskbuffer[0x41] == 0xa0)
if (diskbuffer[0x42] == 0x20)
if (diskbuffer[0x43] == 0x40)
{
PentagonCount++;
Pentagon = TRUE;
}
if (iptr[0x40/4] == 0x13fc00a0)
{
DDocCount++;
DDoc = TRUE;
}
if (iptr[0x150/4] == 0x000100bf)
{
GRAFFITICount++;
GRAFFITI = TRUE;
}
if (iptr[0x150/4] == 0x3fff2c78)
{
Bit16Count++;
Bit16 = TRUE;
}
if (iptr[0x40/4] == 0x4240323c)
{
PhantasmCount++;
Phantasm = TRUE;
}
if (iptr[0x40/4] == 0x0007ec1a)
{
OldNStarCount++;
OldNStar = TRUE;
}
if (iptr[0x1d0/4] == 0x83353ef0)
/*
diskbuffer[0x1d0] == 0x83)
if (diskbuffer[0x1d1] == 0x35)
if (diskbuffer[0x1d2] == 0x3e)
if (diskbuffer[0x1d3] == 0xf0)
*/
{
UFoxCount++;
UFox = TRUE;
}
if (diskbuffer[0x40] == 0x51)
if (diskbuffer[0x41] == 0xc8)
if (diskbuffer[0x42] == 0xff)
if (diskbuffer[0x43] == 0xfc)
{
HCSCount++;
HCS = TRUE;
}
if (diskbuffer[0x40] == 0x03)
if (diskbuffer[0x41] == 0x61)
if (diskbuffer[0x42] == 0x34)
if (diskbuffer[0x43] == 0x3c)
{
LamerXCount++;
LamerX = TRUE;
}
if (diskbuffer[0x34] == 100)
if (diskbuffer[0xc4] == 48)
if (diskbuffer[0xc0] == 68)
if (diskbuffer[0xf1] == 7)
{
ByteWarriorCount++;
ByteWarrior = TRUE;
};
if (diskbuffer[0x2b] == '9')
if (diskbuffer[0x2c] == '.')
if (diskbuffer[0x2d] == '8')
if (diskbuffer[0x2e] == '7')
{
ByteBanditCount++;
BBandit = TRUE; /* 9.87 is part of BBandit Virus */
};
/* check specifically for SCA virus */
if (diskbuffer[0x149] == 0x28)
if (diskbuffer[0x14a] == 0x23)
if (diskbuffer[0x14b] == 0x7c)
{
SCA = TRUE; /* CHW is part of SCA virus */
SCACount++;
};
if (diskbuffer[0xe] == 'I')
if (diskbuffer[0xf] == 'D')
if (diskbuffer[0x10] == '9')
if (diskbuffer[0x1a6] == 'f')
{
Revenge= TRUE;
RevengeCount++;
};
if (diskbuffer[0x12] == 78)
if (diskbuffer[0x13c] == 68)
if (diskbuffer[0x18] == 83)
if (diskbuffer[0x19] == 116)
{
NorthStar = TRUE;
NorthStarCount++;
};
if (diskbuffer[0x38] == 71)
if (diskbuffer[0xbc] == 83)
if (diskbuffer[0x1fb] == 100)
if (diskbuffer[0x2d] == 80)
{
Obelisk = TRUE;
ObeliskCount++;
};
/* compare boot block with real boot block. If it's not, notify God. */
Virus = FALSE;
for (x = 0; x < 39; x++) /* num of bytes in bootblock */
{
if (diskbuffer[8+x] != bootblock[8+x])
{
Virus = TRUE;
};
};
/* Oh no, a Virus! */
if (Virus == TRUE)
{
NBCTEXT[23] = '0'+Unit; /* change DF9: to real drive in text */
TEXTPTR[23] = '0'+Unit;
error = FALSE;
if (SCA == TRUE)
{
/* OH NOOOOO, an SCA virus. Wimpo virus, compared to BBandit
but it's a lot nicer code to read. */
error = MyRequest(VN_SCA, 1);
}
else if (BBandit == TRUE)
{
/* The Byte Bandit Virus. Tricky bugger, he WAS. Cheats, tho. */
sprintf(CopyText, copystring, (long)(diskbuffer[74]*256)+diskbuffer[75]);
BuildITBodyText(VN_BYTEBANDIT, 1);
error = AutoRequest(Window, &BBDiskbody, &SCAPos, &SCANeg, 0L, 0L, 380L, 80L);
}
else if (Revenge == TRUE)
{
/* Revenge virus. X rated bugger, lot like Byte Bandit. */
sprintf(CopyText, copystring, (long)(diskbuffer[0x3f6]*256)+diskbuffer[0x3f7]);
BuildITBodyText(VN_REVENGE, 1);
error = AutoRequest(Window, &RevDiskbody, &SCAPos, &SCANeg, 0L, 0L, 380L, 80L);
}
else if (ByteWarrior == TRUE)
{
/* Byte Warrior. Very 'friendly' virus. Ez to get rid of. */
error = MyRequest(VN_BYTEWARRIOR, 1);
}
else if (Pentagon == TRUE)
{
/* Pentagon Circle. An 'AntiVirus', and not a bad one at that. */
error = MyRequest(VN_PENTAGON, 1);
}
else if (NorthStar == TRUE)
{
/* NorthStar. Nice virus - alerts you to others, ez to get rid of */
error = MyRequest(VN_NORTHSTAR, 1);
}
else if (Obelisk == TRUE)
{
/* At least these guys are getting creative with their Graphics! */
error = MyRequest(VN_OBELISK, 1);
}
else if (LamerX == TRUE)
{
/* At least these guys are getting creative with their Graphics! */
error = MyRequest(VN_LAMER, 1);
}
else if (HCS == TRUE)
{
/* At least these guys are getting creative with their Graphics! */
error = MyRequest(VN_HCS, 1);
}
else if (UFox == TRUE)
{
/* yawn */
error = MyRequest(VN_UFOX, 1);
}
else if (DDoc == TRUE)
{
/* yawn */
error = MyRequest(VN_DDOC, 1);
}
else if (GRAFFITI == TRUE)
{
/* yawn */
error = MyRequest(VN_GRAFFITI, 1);
}
else if (Bit16 == TRUE)
{
/* yawn */
error = MyRequest(VN_Bit16, 1);
}
else if (Phantasm == TRUE)
{
/* yawn */
error = MyRequest(VN_PHANTASM, 1);
}
else if (OldNStar == TRUE)
{
/* yawn */
error = MyRequest(VN_OLDNSTAR, 1);
}
else
{
/* Probably just a custom boot block (or a new virus...) */
error = AutoRequest(Window, &Body1, &SCAPos, &SCANeg, 0L, 0L, 320L, 70L);
}
if (error == TRUE) DoInstall(Unit); /* user wants it neutered. */
};
CheckDriveForIRQ(drivename);
}; /* End of While Whochanged */
}
/********************************************/
/* This is where the boot code gets changed */
/********************************************/
DoInstall(un)
int un; /* unit to write to */
{
register int x;
/* Rewrite disk? Really? */
error = AutoRequest(Window, &REWBody, &REWPos, &REWNeg, 0L, 0L, 320L, 75L);
if (error != TRUE) return; /* user changed his brain. */
DisksInstalled++;
error = OpenDevice(TDName, (long)un,diskreq,0L);
if (error > 0) return;
TryGain:
diskreq->io_Command = TD_PROTSTATUS;
DoIO(diskreq); /* check if disk is write protected */
if (diskreq->io_Actual != 0)
{
error = AutoRequest(Window, &ERRBody, &ERRPos, &ERRNeg, 0L, 0L, 280L, 75L);
if (error == TRUE) /* error is true or false, depending on user */
{
goto TryGain;
};
CloseDevice(diskreq);
return; /* unrecoverable write protect error!! Panic!!!!!!! */
};
for (x = 0; x < 1024; x++)
diskbuffer[x] = 0; /* clear diskbuffer to zero. clean. */
CopyMem(bootblock, diskbuffer, 50L); /* Copy it over */
/* Write it ! */
error = 0;
diskreq->io_Length = 1024; /* here we go! */
diskreq->io_Data = (APTR)diskbuffer;
diskreq->io_Command = CMD_WRITE;
diskreq->io_Offset = 0L;
DoIO(diskreq);
error = diskreq->io_Error;
if (error < 19)
{
diskreq->io_Command = CMD_UPDATE; /* flush buffer to disk */
DoIO(diskreq);
error = diskreq->io_Error;
};
if (error < 19)
{
diskreq->io_Length = 0;
diskreq->io_Command = ETD_MOTOR;
DoIO(diskreq); /* turn off motor */
error = diskreq->io_Error;
};
CloseDevice(diskreq);
if (error > 19)
{
SetWindowTitles(Window, "Disk Error!", (STRPTR)-1);
}
else
{
SetWindowTitles(Window, "Disk Healed.", (STRPTR)-1);
};
Delay(150L);
SetWindowTitles(Window, TITLETEXT, (STRPTR)-1);
}
/************************/
CheckMemoryForViruses()
{
unsigned long *TD;
unsigned short *wordpointer;
unsigned long *LongMemPointer; /* Used for reading FROM memory */
unsigned long *ptr;
char linebuffer[80];
char *charpointer;
unsigned int x;
/**************- Check for Byte Bandit (look at TD Vector) *************/
/* (Byte Bandit isn't at a fixed location. Depends on your RAM. */
/* LongMemPointer = &trackdisk.device */
TD = (unsigned long *)FindName(&ExecBase->DeviceList, TDName);
x = (unsigned int) TD;
x = x - 0x1c;
ptr = (unsigned long *) x;
LongMemPointer = (unsigned long *) *ptr;
x = (unsigned int) LongMemPointer;
x = x - 0x1b8;
LongMemPointer = (unsigned long *) x;
if (*LongMemPointer == ID_DOS_DISK) /* klugo */
{
/* Ok, so we don't really remove it from memory, but we DO render
it harmless. */
Disable();
charpointer = (char *)VirusBase;
charpointer[0xaa] = 0x4e;
charpointer[0xac] = 0x4e;
charpointer[0xae] = 0x4e;
charpointer[0xb0] = 0x4e;
charpointer[0xab] = 0x71;
charpointer[0xad] = 0x71;
charpointer[0xaf] = 0x71; /* Isn't this code terrible? Ick! */
charpointer[0xb1] = 0x71; /* I didn't know what I was doing when */
charpointer[0x1c2] = 0x60; /* I wrote this. (excuses... 8-) */
charpointer[0x1c3] = 0;
charpointer[0x2d2] = 0x60;
charpointer[0x2d3] = 0;
charpointer[0x388] = 0x4e;
charpointer[0x389] = 0x75;
charpointer[0x3ea] = 0;
charpointer[0x3eb] = 0;
charpointer[0] = 0;
Enable();
MyRequest(VN_BYTEBANDIT, 2);
};
TD = (unsigned long *)FindName(&ExecBase->DeviceList, TDName);
x = (unsigned int) TD;
x = x - 0x1c;
LongMemPointer = (unsigned long *)x;
LongMemPointer = (unsigned long *)LongMemPointer[0];
x = (unsigned int)LongMemPointer;
x = x - 0x17c;
LongMemPointer = (unsigned long *)x;
if (*LongMemPointer == ID_DOS_DISK) /* ptr == VirusBase */
{
char *a;
long *src, *dest;
long *vbase;
*LongMemPointer = 0; /* Kill DOS\0 */
vbase = LongMemPointer;
/* Disable, then repair vectors. */
Disable();
/* addr of real TD vector */
src = &vbase[0x3a8/4];
a = (char *)ExecBase;
a = a - 0x264;
dest = (unsigned long *)a;
*dest = *src;
src = (unsigned long *) &vbase[0x3ac/4];
a = (char *)TD;
a = a - 0x1c;
dest = (unsigned long *)a;
*dest = *src;
Enable();
ExecBase->KickTagPtr = 0; /* Sorry, I know it's cruel */
MyRequest(VN_LAMER, 2);
}
/****************- Look for Revenge Virus (at $7e000) ****************/
if ((unsigned long)ExecBase->CoolCapture == (unsigned long)516192)
{
/* Fix the CoolCapture vector */
ExecBase->CoolCapture = 0;
Disable();
wordpointer = (unsigned short *)(0x7e000);
wordpointer[0] = 0;
wordpointer = (unsigned short *)(0x7e000+0x1e0);
wordpointer[0] = 0x4ef9;
wordpointer[1] = 0x0007;
wordpointer[2] = 0xe066;
wordpointer = (unsigned short *)0x7e2da;
wordpointer[0] = 0x4ef9;
wordpointer[1] = 0x0007;
wordpointer[2] = 0xe06c;
Enable();
MyRequest(VN_REVENGE, 2);
};
/******************** See if SCA is in RAM ***************************/
if ((long)ExecBase->CoolCapture == (long)0x7ec3e)
{
ExecBase->CoolCapture = 0;
MyRequest(VN_SCA, 2);
};
/******************** See if Graffiti is in RAM ***************************/
if ((long)ExecBase->CoolCapture == (long)0x7ec58)
{
ExecBase->CoolCapture = 0;
MyRequest(VN_GRAFFITI, 2);
};
/******************** How about Phantasmumble? ***************************/
if ((long)ExecBase->CoolCapture == (long)0x7ec74)
{
ExecBase->CoolCapture = 0;
MyRequest(VN_PHANTASM, 2);
};
/******************** Yoo hoo? HCS? Are you here? ******************/
if ((long)ExecBase->CoolCapture == (long)0x7ec64)
{
/* You are, you little dickens. */
ExecBase->CoolCapture = 0;
/* Scat! */
x = (unsigned int) ExecBase;
x = x - 0x1c6;
ptr = (unsigned long *)x;
LongMemPointer = (unsigned long *)0x7ef9c;
*ptr = *LongMemPointer; /* un-Step on DoIO() vector */
MyRequest(VN_HCS, 2);
};
/**************************** DiskDoktor? ****************************/
wordpointer = ExecBase->CoolCapture;
if (*wordpointer == 0x2c79)
{
if (wordpointer[3] == 0x203c)
{
int x;
Disable();
x = ExecBase;
x = x - 0x1c6;
LongMemPointer = (long *)x;
wordpointer = (UWORD *)*LongMemPointer;
x = (int)wordpointer;
x = x + (0x15c);
wordpointer = (UWORD *)x;
*wordpointer = 0x4e75;
x = (int)wordpointer;
x = x + 0x1e2;
wordpointer = (UWORD *)x;
*wordpointer = 0x4e75;
x = (int)ExecBase;
x = x - 0x1c6;
ptr = (long *)x;
x = (int)*ptr;
x = x + 2;
LongMemPointer = (long *)x;
*ptr = *LongMemPointer;
ExecBase->CoolCapture = 0;
ExecBase->ColdCapture = 0;
ExecBase->WarmCapture = 0;
Enable();
MyRequest(VN_DDOC, 2);
};
};
/******************** It's the Australian UltraFox ******************/
if ((long)ExecBase->CoolCapture == (long)0x7ed36)
{
UWORD *wordptr;
ExecBase->CoolCapture = 0;
x = (unsigned int) ExecBase;
x = x - 0x1c6;
ptr = (unsigned long *)x;
wordptr = (UWORD *)ptr;
if (wordptr[0] == 0x0007)
{
LongMemPointer = (unsigned long *)0x7eb38;
*ptr = *LongMemPointer; /* un-Step on DoIO() vector */
};
MyRequest(VN_UFOX, 2);
};
/***************** Check for Obelisk *******************************/
if ((APTR)ExecBase->CoolCapture == (APTR)0x7e86c)
{
ExecBase->CoolCapture = 0;
ptr = (unsigned long *)0x7e88a;
Forbid();
ptr[0] = 10;
Permit();
MyRequest(VN_OBELISK, 2);
};
/******************** How about North Star? **************************/
if ((APTR)ExecBase->CoolCapture == (APTR)0x7ec0e)
{
ExecBase->CoolCapture = 0;
MyRequest(VN_NORTHSTAR, 2);
};
/********************* Check for Byte Warrior ************************/
wordpointer = (unsigned short *)0x7f800;
if ( wordpointer[0] == (0x444f) )
{
wordpointer = (unsigned short *)0x7f954;
if (wordpointer[0] == 0x4afc)
{
wordpointer[0] = 0; /* Kill resident matchtag */
Forbid();
wordpointer = (unsigned short *)0x7f972;
wordpointer[0] = 0x4ef9;
wordpointer[1] = 0x00fc;
wordpointer[2] = 0x06dc;
wordpointer = (unsigned short *)0x7f800;
wordpointer[0] = 0;
Permit();
MyRequest(VN_BYTEWARRIOR, 2);
};
};
/******************** See if Pentagon is in RAM ***************************/
if ((long)ExecBase->CoolCapture == (long)0x7fb4c)
{
ExecBase->CoolCapture = 0;
/* He sometimes has the DoIO() setfunctioned, I can't figure out
when, but even if he does, he doesn't do any harm anyway, and
with CoolCapture set to 0, he'll be gone at next reboot. */
MyRequest(VN_PENTAGON, 2);
};
if (ExecBase->CoolCapture != 0)
{
sprintf(linebuffer, "Cool%s%lx", CaptureStr, ExecBase->CoolCapture);
if (MyRequest(linebuffer, 3) == TRUE) ExecBase->CoolCapture = 0;
}
if (ExecBase->ColdCapture != 0)
{
sprintf(linebuffer, "Cold%s%lx", CaptureStr, ExecBase->ColdCapture);
if (MyRequest(linebuffer, 3) == TRUE) ExecBase->ColdCapture = 0;
}
if (ExecBase->WarmCapture != 0)
{
sprintf(linebuffer, "Warm%s%lx", CaptureStr, ExecBase->WarmCapture);
if (MyRequest(linebuffer, 3) == TRUE) ExecBase->WarmCapture = 0;
}
}
/**************************************************************/
/* This is the routine that displauys a block as ASCII text. */
/**************************************************************/
ShowAscii(key)
long key;
{
int drive;
int x,y;
int deltax, deltay;
long a;
int FLAG=0;
struct RastPort *RP;
RP = Window->RPort;
drive = key - '0';
if ((drive < 0) || (drive > 3) || (ChangeCount[drive] == -1)) return;
error = OpenDevice(TDName,(long)drive,diskreq,0L);
if (error > 0) return;
error = ReadBlock();
CloseDevice(diskreq);
if (error == FALSE) return;
/* save the amount we moved the window */
deltax = Window->LeftEdge;
deltay = Window->TopEdge;
MoveWindow(Window, -deltax, -deltay);
if (WindowBig == FALSE) SizeWindow(Window, 278L, 160L);
else SizeWindow(Window, 278L, 0L);
WaitForNewSize();
SetAPen(RP, 0L);
RectFill(RP, 2, 12, 278, 167);
SetAPen(RP, 3L);
Move(RP, (long)(14+(12*8)), 165L);
Text(RP, "Block 0", 7L);
Move(RP, (long)(324+(12*8)), 165L);
Text(RP, "Block 1", 7L);
SetAPen(RP, 1L);
text[2] = key;
SetWindowTitles(Window, text, (STRPTR)-1);
x=0; y=0;
SetAPen(RP, 1L);
SetDrMd(RP, JAM2);
for (a=0; a<512; a=a+32)
{
Move(RP, (long)(10+(x*8)), (long)20+(y*9));
Text(RP, &diskbuffer[a], 32L);
Move(RP, (long)(320+(x*8)), (long)20+(y*9));
Text(RP, &diskbuffer[a+512], 32L);
y++;
};
Wait(1<<Window->UserPort->mp_SigBit);
Message = (struct IntuiMessage *)GetMsg(Window->UserPort);
/* If a disk was inserted, we want CheckBlock() to happen later on some time */
if (Message->Class == DISKINSERTED) FLAG=1;
ReplyMsg((struct Message *)Message);
if (WindowBig == FALSE)
SizeWindow(Window, -278L, -160L);
else SizeWindow(Window, -278L, 0L);
SetWindowTitles(Window, TITLETEXT, (STRPTR)-1);
WaitForNewSize();
/* deltas plus current position, in case dude moved the window */
MoveWindow(Window, deltax+(-Window->LeftEdge), deltay+(-Window->TopEdge));
Delay(2L);
return(FLAG);
}
/*
When you do a SizeWindow() command, you have to wait for a NEWSIZE
IntuiMessage before drawing in it. That's all this routine does.
*/
WaitForNewSize()
{
while (TRUE)
{
WaitPort(Window->UserPort);
Message = (struct IntuiMessage *)GetMsg(Window->UserPort);
if (Message->Class != NEWSIZE)
{
ReplyMsg((struct Message *)Message);
continue;
};
ReplyMsg((struct Message *)Message);
break;
};
}
/*
type:
1 == "is infected with the xxxx VIRUS!"
2 == "somethin about virus in ram"
3 == virus in cold/cool/warm capture
*/
BuildITBodyText(text, type)
char *text;
int type;
{
switch (type)
{
case 1:
strcpy(ITBodyText, "infected with the `");
strcat(ITBodyText, text);
strcat(ITBodyText, "' VIRUS!");
break;
case 2:
strcpy(ITBodyText, "NOTICE: The `");
strcat(ITBodyText, text);
strcat(ITBodyText, "' VIRUS was found");
break;
};
}
/***** an attempt to save space *********/
MyRequest(string, type)
char *string;
int type;
{
if (type != 3)
{
BuildITBodyText(string, type);
} else
{
Mem1.IText = string;
};
if (type == 1) return(AutoRequest(Window, &GenericDiskBody, &SCAPos, &SCANeg, 0L, 0L, 420L, 80L));
if (type == 2) return(AutoRequest(Window, &GenericRAMBody, &BBMPos, &BBMPos, 0L, 0L, 420L, 78L));
if (type == 3) return(AutoRequest(Window, &Mem1, &Repair, &SCANeg, 0L, 0L, 420L, 78L));
}
/********* DoStats() **********/
DoStats()
{
char linebuffer[80];
SetAPen(RP, 0L);
RectFill(RP, 2L, 11L, 303L, Window->Height-13);
SetAPen(RP, 1L);
sprintf(linebuffer, " Disks Checked: %ld", DisksChecked);
Out(20, linebuffer);
sprintf(linebuffer, "Disks Installed: %ld", DisksInstalled);
Out(29, linebuffer);
Out(43, " Viruses Found:");
PV(52, VN_SCA, SCACount);
PV(61, VN_BYTEBANDIT, ByteBanditCount);
PV(70, VN_NORTHSTAR, NorthStarCount);
PV(79, VN_BYTEWARRIOR, ByteWarriorCount);
PV(88, VN_REVENGE, RevengeCount);
PV(97, VN_OBELISK, ObeliskCount);
PV(106, VN_IRQ, IRQFound);
PV(115, VN_PENTAGON, PentagonCount);
PV(124, VN_HCS, HCSCount);
PV(133, VN_DDOC, DDocCount);
PV(142, VN_GRAFFITI, GRAFFITICount);
PV(151, VN_Bit16, Bit16Count);
PV(160, VN_PHANTASM, PhantasmCount);
PV(169, VN_OLDNSTAR, OldNStarCount);
PV(178, VN_UFOX, UFoxCount);
PV(187, VN_LAMER, LamerXCount);
}
/****************** Ok, we're REALLY being chintzy here. */
PV(num, name, howmany)
int num;
char *name;
int howmany;
{
char linebuffer[80];
sprintf(linebuffer, "%-19s: %ld", name, howmany);
Out(num, linebuffer);
}
/***************************************** Cheap? Me? Nooooo.... */
/* This will write text to the column number in NUM, the text in Name. */
/* Or something like that. ********************************************/
Out(num, name)
int num;
char *name;
{
int len;
len = 0;
while (name[len] != 0) len++;
Move(RP, 20L, (long)num);
Text(RP, name, len);
}
ReadBlock()
{
diskreq->io_Command = CMD_READ;
diskreq->io_Data = (APTR)diskbuffer;
diskreq->io_Length = 3*512;
diskreq->io_Offset = 0;
DoIO(diskreq);
if (diskreq->io_Error > 0) return(FALSE);
diskreq->io_Length = 0;
diskreq->io_Command = TD_MOTOR;
DoIO(diskreq);
return(TRUE);
}
unsigned long *OpenLibVectorPtr;
unsigned long *EntryForOldOpenLib;
unsigned long *OldOldOpenLibVector;
CheckMemoryForIRQVirus()
{
long *Array;
int Num;
Array = (long *)4;
Array = (long *)Array[0];
Num = (int)Array;
Num = Num - 0x196;
OpenLibVectorPtr = (unsigned long *)Num;
EntryForOldOpenLib = (unsigned long *)OpenLibVectorPtr[0];
OldOldOpenLibVector = (unsigned long *)(((char *)EntryForOldOpenLib) + 0x12);
if (EntryForOldOpenLib[0] == 0x2f3a0010)
{
OpenLibVectorPtr[0] = OldOldOpenLibVector[0];
ExecBase->KickTagPtr = 0;
MyRequest(VN_IRQ, 2);
};
}
/********************************/
CheckDriveForIRQ(drivename)
char *drivename;
{
int err;
char buffer[80];
char dirbuffer[80];
char filebuffer[100];
char tempbuffer[100];
char FoundInDir;
char FoundInFname;
char chr;
int index;
char pass;
FoundInDir = FALSE;
FoundInFname = FALSE;
filebuffer[0] = 0;
pass = 0;
sprintf(dirbuffer, "%sC/DIR", drivename);
err = CheckFileForIRQ(dirbuffer,0);
if (err == 1)
{
IRQFound++;
FoundInDir = TRUE;
}
else dirbuffer[0] = 0;
index = 0;
sprintf(tempbuffer, "%ss/Startup-Sequence", drivename);
fp = Open(tempbuffer, MODE_OLDFILE);
if (fp == 0)
filebuffer[0] = 0;
else
{
while (TRUE)
{
err = Read(fp, &chr, 1);
if (err == 0) break;
if ((chr == 34) || (chr == 0x0a) || (chr == ';') || (chr == ' ')) continue;
break;
};
if (err != 0)
{
while (TRUE)
{
filebuffer[index++] = chr;
filebuffer[index] = 0;
err = Read(fp, &chr, 1);
if (err == 0) break;
if (chr == 34) break;
if (chr == 0x0a) break;
if (chr == ';') break;
if (chr == 32) break;
};
};
Close(fp);
sprintf(buffer, "%s%s", drivename, filebuffer);
err = CheckFileForIRQ(buffer, 0);
if (err == -1)
{
sprintf(buffer, "C:%s", filebuffer);
err = CheckFileForIRQ(buffer, 0);
};
strcpy(filebuffer, buffer);
if (err == 1)
{
FoundInFname = TRUE;
IRQFound++;
}
else filebuffer[0] = 0;
};
if (FoundInDir == FALSE && FoundInFname == FALSE) return(0);
WBenchToFront();
fp = Open("CON:70/20/500/100/VirusX", MODE_NEWFILE);
if (fp == 0) return(0);
WriteFP(fp, "NOTICE: The IRQ Virus was found on volume ");
WriteFP(fp, drivename);
WriteFP(fp, "\n");
while (TRUE)
{
if (pass == 0)
{
strcpy(tempbuffer, dirbuffer);
}
else if (pass == 1)
{
strcpy(tempbuffer, filebuffer);
}
else if (pass == 2) break;
pass++;
if (tempbuffer[0] == 0) continue;
sprintf(buffer, "\nIn the command: %s\n", tempbuffer);
WriteFP(fp, buffer);
WriteFP(fp, "Okay to remove it? [Y]: ");
Read(fp, buffer, 3);
if (toupper(buffer[0]) == 'Y')
{
err = CheckFileForIRQ(tempbuffer, 1);
if (err == 1)
{
WriteFP(fp, "Virus removed.\n");
} else
{
WriteFP(fp, "Error removing virus. Check file.\n");
}
};
};
WriteFP(fp, "\nHit RETURN to continue...");
Read(fp, buffer, 3);
Close(fp);
}
WriteFP(fp, string)
int fp;
char *string;
{
Write(fp, string, strlen(string));
}
/********************************/
#define VTAG 0x00000109L
#define BEGIN OFFSET_BEGINNING
#define END OFFSET_END
#define OLD MODE_OLDFILE
#define NEW MODE_NEWFILE
#define SLONG ((long)sizeof(long))
#define OK 1 /* no error */
#define NOFILE -1 /* can't find file */
#define SEEKERR -2 /* seek error on file */
#define ALLOCERR -3 /* can't allocate memory */
#define READERR -4 /* error reading file */
#define VIRUSNF -5 /* virus not found in file */
#define WRITERR -6 /* error writing to file */
#define OPENERR -7 /* error opening file for write */
#define NOTEXE -8 /* not an executable file */
#define GOTHIM OK /* removed virus from file */
#define VTAG 0x00000109L /* virus hunk length */
#define VSIG1 0x0000FFFEL /* part of virus signature */
#define VSIG2 0x61000000L /* part of virus signature */
static long inp, *buff, size;
cleanup(val)
int val;
{
if(inp) Close(inp);
if(buff) FreeMem(buff,size);
return val;
}
CheckFileForIRQ(fname, flag)
char *fname;
int flag;
{
int i = 0;
long nhunk;
long tbuff[488/4];
inp = 0L; buff = 0L;
if((inp = Open(fname,OLD)) == 0) /* open the desired file */
return NOFILE;
Read(inp,(char *)&tbuff[0],487); /* get the first long word */
if(tbuff[0] != 0x000003F3) /* check for executable file */
return cleanup(NOTEXE);
if(tbuff[5] != VTAG)
return cleanup(VIRUSNF);
Seek(inp,0L,END); /* seek to end of file */
size = Seek(inp,0L,BEGIN); /* rewind the file to get size */
if(size <= 0L)
return cleanup(SEEKERR);
if((buff = AllocMem(size,0L)) == 0) /* mem buffer for file */
return cleanup(ALLOCERR);
if(Read(inp,(char *)&buff[0],size) != size) /* read entire file into buffer */
return cleanup(READERR);
nhunk = buff[ 2 ]; /* number of hunks in file */
/*
the IRQ virus inserts his code as the first hunk in the file
we can find the first hunk in the 6th longword of the file
*/
/* find the start of the virus hunk */
while(buff[ i++ ] != 0x000003E9)
;
/*
The virus checks the first hunk for it's signature to prevent
reinfecting an already infected program. It actually checks for
0xFFFE6100 which is the lower half of a move.m instruction and
the upper half of a bsr instruction. Here we do the same.
i points to the virus code hunk length.
*/
if( ((buff[ i+1 ] & 0x0000FFFF) != VSIG1)
|| ((buff[ i+2 ] & 0xFFFF0000) != VSIG2) )
return cleanup(VIRUSNF);
if (flag == 0)
return cleanup(1);
/*
close the file and reopen it with write access
mode NEW will effectivly delete the old file contents so if a
file error occurs before we finish, the file will be corrupt
*/
Close(inp);
if((inp = Open(fname,NEW)) == 0)
return cleanup(OPENERR);
buff[2] -= 1; buff[4] -= 1; /* readjust program header info */
/* write new header */
if(Write(inp,(char *)&buff[0],5L*SLONG) != 5L*SLONG)
return cleanup(WRITERR);
if(Write(inp,(char *)&buff[6],nhunk*SLONG) != nhunk*SLONG)
return cleanup(WRITERR);
/*
subtract length of virus hunk and overhead from file size
i was calculated earlier
*/
i = i + 8L + VTAG;
size = (size/SLONG - i)*SLONG;
/* and write old code out to file, ignoring virus hunk */
if(Write(inp,(char *)&buff[i],size) != size)
return cleanup(WRITERR);
/* we're done, the file is clean and intact */
return cleanup(GOTHIM);
}